//
// Created by guts on 6/24/21.
//

#ifndef GDBUS_CARPLAYINTERFACE_H
#define GDBUS_CARPLAYINTERFACE_H

//#include "generate/GDbusCarPlay.h"
#ifdef  __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stddef.h>
#include "DebugServices.h"

typedef void (*CarPlayInterfaceSendEnd_f)();

typedef void (*CarPlayInterfaceSendInitialModesCommand_f)(const char* arg_command);

typedef void (*CarPlayInterfaceSendInitialChangeModes_f)(
    const char*            arg_screenBorrowId,
    int                    arg_screenType,
    int                    arg_screenPriority,
    int                    arg_screenTake,
    int                    arg_screenBorrow,
    const char*            arg_audioBorrowId,
    int                    arg_audioType,
    int                    arg_audioPriority,
    int                    arg_audioTake,
    int                    arg_audioBorrow,
    int                    arg_phone,
    int                    arg_speech,
    int                    arg_turnByTurn,
    int                    arg_screenPermanentEntity,
    int                    arg_screenPermanentTakeConstraint,
    int                    arg_screenPermanentBorrowConstraint,
    int                    arg_audioPermanentEntity,
    int                    arg_audioPermanentTakeConstraint,
    int                    arg_audioPermanentBorrowConstraint);

typedef void (*CarPlayInterfaceSendChangeModes_f)(
    const char*            arg_screenBorrowId,
    int                   arg_screenType,
    int                   arg_screenPriority,
    int                   arg_screenTake,
    int                   arg_screenBorrow,
    const char*            arg_audioBorrowId,
    int                   arg_audioType,
    int                   arg_audioPriority,
    int                   arg_audioTake,
    int                   arg_audioBorrow,
    int                   arg_phone,
    int                   arg_speech,
    int                   arg_turnByTurn);

typedef void (*CarPlayInterfaceSendChangeResourceMode_f)(
    const char*             arg_borrowID,
    int                    arg_resourceId,
    int                    arg_type,
    int                    arg_priority,
    int                    arg_takeConstraint,
    int                    arg_borrowConstraint);

typedef void (*CarPlayInterfaceSendChangeAppState_f)(
    int                    arg_speech,
    int                    arg_phone,
    int                    arg_turnByTurn);




typedef void (*CarPlayInterfaceSendRequestUi_f)();

typedef void (*CarPlayInterfaceSendRequestUiWithUrl_f)(const char* arg_url);

typedef void (*CarPlayInterfaceSendSetNightMode_f)(
    int                    arg_nightMode);

typedef void (*CarPlayInterfaceSendUiAppearanceUpdate_f)(int arg_mode, int arg_setting);

typedef void (*CarPlayInterfaceSendSetLimitedUI_f)(int limitUI);

typedef void (*CarPlayInterfaceSendRequestSiriAction_f)(
    int                     arg_action);

typedef int32_t (*CarPlayInterfaceSendTouchScreenUpdate_f)(
    uint8_t                   arg_press,
    uint16_t                  arg_x,
    uint16_t                  arg_y);

typedef int32_t (*CarPlayInterfaceSendTelephonyUpdate_f)(int  index);
typedef int32_t (*CarPlayInterfaceSendMediaButtonUpdate_f)(int            index);
typedef OSStatus(*CarPlayInterfaceSendForceKeyFrame_f)();
typedef OSStatus (*CarPlayInterfaceSendKnob_f)(
                    char    selectButtonPressed,
                    char    homeButtonPressed,
                    char    backButtonPressed,
                    double  x,
                    double  y,
                    char    wheelPositionRelative);



// typedef void (*CarPlayInterface_f)();

typedef struct {
    CarPlayInterfaceSendInitialModesCommand_f   initialModesCommand_f;
    CarPlayInterfaceSendInitialChangeModes_f    initialChangeModes_f;
    CarPlayInterfaceSendChangeModes_f           changeMode_f;
    CarPlayInterfaceSendChangeResourceMode_f    changeResourceMode_f;
    CarPlayInterfaceSendChangeAppState_f        changeAppState_f;
    CarPlayInterfaceSendRequestUi_f             requestUi_f;
    CarPlayInterfaceSendRequestUiWithUrl_f      requestUiWithUrl_f;
    CarPlayInterfaceSendSetNightMode_f          setNightMode_f;
    CarPlayInterfaceSendUiAppearanceUpdate_f    uiAppearanceUpdate_f;
    CarPlayInterfaceSendSetLimitedUI_f          setLimitedUI_f;
    CarPlayInterfaceSendRequestSiriAction_f     requestSiriAction_f;
    CarPlayInterfaceSendTouchScreenUpdate_f     touchScreenUpdate_f;
    CarPlayInterfaceSendTelephonyUpdate_f       telephonyUpdate_f;
    CarPlayInterfaceSendMediaButtonUpdate_f     mediaButtonUpdate_f;
    CarPlayInterfaceSendEnd_f                   end_f;
    CarPlayInterfaceSendForceKeyFrame_f         forceKeyFrame_f;
    CarPlayInterfaceSendKnob_f                  knob_f;
} CarPlayInterfaceDelegate;

#define CarPlayInterfaceDelegateInit( PTR ) memset( (PTR), 0, sizeof( CarPlayInterfaceDelegate ) );

void CarPlayInterfaceSetDelegate(const CarPlayInterfaceDelegate* inDelegate);

void handleSessionCreated();
void handleSessionStarted(const char* arg_macAddress);
void handleSessionFinalized();
void handleSessionModesChanged(
    int arg_screen,
    int arg_permScreen,
    int arg_audio,
    int arg_permAudio,
    int arg_speechEntity,
    int arg_speechMode,
    int arg_phoneCall,
    int arg_turnByTurn);
void handleSessionRequestUi();
void handleSessionDuckAudio(
    double arg_durationSecs,
    double arg_volume);
void handleSessionUnduckAudio(double arg_durationSecs);
void handleSessionControlDisableBluetooth(const char* arg_address);
void handleScreenStreamStart();
void handleScreenStreamDataProc(const uint8_t* buf, int len);
void handleScreenStreamStop();
void handleAudioStreamStart(const char* audioType, int handle, int streamType, int rate, int bits,
                            int channels, void*  inStream);
//void handleAudioStreamStop( const char *audioType, int handle );
void handleAudioStreamStop(int handle, int type);
void handleCarPlayExit();
int handleCarPlaySwitchUsbModel(int mode);

char* handleMfiDevName();

//=================================================================================================================
// iAP2Interface
//=================================================================================================================

typedef void (*iAP2InterfaceSendSetup_f)(
    int                     arg_type,
    uint16_t                  arg_vendorId,
    uint16_t                  arg_productId,
    const char*              arg_address,
    int                     arg_same);

typedef void (*iAP2InterfaceSendNmeaSentence_f)(const char* arg_nmeaSentence);

typedef void (*iAP2InterfaceSendPascdSentence_f)(char transmissionState, int sampleCount, double* speed);

typedef void (*iAP2InterfaceSendRfcommData_f)(char* arg_ptr, int arg_length);

typedef void (*iAP2InterfaceSendWiFiInformation_f)(
    const char*            arg_ssid,
    const char*            arg_passphrase,
    int                    arg_securityType,
    int8_t            arg_channel);

typedef void (*iAP2InterfaceSendBluetoothPairingAccessoryInformation_f)(char* inPairingDataP192,
                                                                        char* inPairingDataP256);

typedef void (*iAP2InterfaceSendBluetoothPairingStatus_f)(int arg_success, const char* arg_cancelReason);

typedef void (*iAP2InterfaceSendCarPlayStartSession_f)(int allow);

typedef void (*iAP2InterfaceSendOobBtPairingCompletionInformation_f)(int resultCode);

typedef void (*iAP2InterfaceSendResetMusicList_f)();

typedef void (*iAP2InterfaceSendSelectMusicList_f)(int arg_index);

typedef void (*iAP2InterfaceSendBackMusicList_f)();

typedef void (*iAP2InterfaceSendGetMusicList_f)(int arg_index, int arg_count);

typedef void (*iAP2InterfaceSendGetMusicPlayList_f)(int arg_index, int arg_count);

typedef void (*iAP2InterfaceSendSelectMusicPlayList_f)(int arg_index);

typedef void (*iAP2InterfaceSetMacAddr_f)(char* mac_addr);
typedef struct {
    iAP2InterfaceSendSetup_f                    setup_f;
    iAP2InterfaceSendNmeaSentence_f             sendNmeaSentence_f;
    iAP2InterfaceSendPascdSentence_f            sendPascdSentence_f;
    iAP2InterfaceSendRfcommData_f               sendRfcommData_f;
    iAP2InterfaceSendWiFiInformation_f          sendWiFiInformation_f;
    iAP2InterfaceSendCarPlayStartSession_f      sendCarPlayStartSession_f;
    iAP2InterfaceSendBluetoothPairingAccessoryInformation_f     sendBluetoothPairingAccessoryInformation_f;
    iAP2InterfaceSendBluetoothPairingStatus_f                   sendBluetoothPairingStatus_f;
    iAP2InterfaceSendOobBtPairingCompletionInformation_f        sendOobBtPairingCompletionInformation_f;
    iAP2InterfaceSendResetMusicList_f           sendResetMusicList_f;
    iAP2InterfaceSendSelectMusicList_f          sendSelectMusicList_f;
    iAP2InterfaceSendBackMusicList_f            sendBackMusicList_f;
    iAP2InterfaceSendGetMusicList_f             sendGetMusicList_f;
    iAP2InterfaceSendGetMusicPlayList_f         sendGetMusicPlayList_f;
    iAP2InterfaceSendSelectMusicPlayList_f      sendSelectMusicPlayList_f;
    iAP2InterfaceSetMacAddr_f           setMacAddr_f;

} iAP2InterfaceDelegate;

#define iAP2InterfaceDelegateInit( PTR )    memset( (PTR), 0, sizeof( iAP2InterfaceDelegate ) );

void iAP2InterfaceSetDelegate(const iAP2InterfaceDelegate* inDelegate);

void handleCallStateUpdate(
    const char*    arg_remoteId,
    const char*    arg_displayName,
    int            arg_status,
    int            arg_direction);
void handleNowPlayingUpdatePlaybackAttributes(
    int arg_playbackStatus,
    int arg_playbackShuffleMode,
    int arg_playbackRepeatMode,
    int arg_playbackElapsedTime);
void handleNowPlayingUpdateMediaItemAttributes(
    const char*    arg_mediaItemTitle,
    const char*    arg_mediaItemAlbumTitle,
    const char*    arg_mediaItemArtist,
    int            arg_mediaItemDuration);
void handleDeviceInformationUpdate(const char* name);
void handleRfcommData(const char* data, int length);
void handleIdentifierNotificationUpdated(
    const char*     arg_BluetoothTransportIdentifier,
    const char*     arg_UsbTransportIdentifier);
void handleCarPlayAvailable(int available);
void handleRouteGuidanceUpdate(
    int            arg_routeGuidanceState,
    int            arg_maneuverState,
    const char*    arg_currentRoadName,
    const char*    arg_destinationName,
    const char*    arg_distanceRemainingDisplayString,
    int            arg_distanceRemainingDisplayUnits,
    const char*    arg_distanceToNextManeuverDisplayStr,
    int            arg_distanceToNextManeuverDisplayUnits,
    int            arg_timeRemainingHours,
    int            arg_timeRemainingMinutes);
void handleRouteGuidanceManeuverInformation(
    int            arg_maneuverType,
    const char*    arg_afterManeuverRoadName,
    int            arg_drivingSide);
void handleStartBluetoothPairing(const char* arg_deviceMacAddress);
void handleOobBtPairingLinkKeyInformation(
    const char*    arg_linkKey,
    int            arg_length,
    const char*    arg_deviceMacAddress);
void handleMediaLibraryUpdateProgress(int arg_progress);
void handleMediaItemArtworkFileTransferIdentifier(const char* arg_path);
void handleMediaPlayListUpdate(int index);
void handlePlaybackQueueListAvailable(int available);
void handlePlayListInfo(const char* arg_ptr, int arg_length);
bool KnobUpdate(char    selectButtonPressed,
                    char    homeButtonPressed,
                    char    backButtonPressed,
                    double  x,
                    double  y,
                    char    wheelPositionRelative);

void CarPlayInterfaceInitialized();

bool sendSetup(
    int                     arg_type,
    uint16_t                  arg_vendorId,
    uint16_t                  arg_productId,
    const char*              arg_address,
    int                     arg_same);
bool    sendEnd(void);
bool sendRequestUi();
bool sendRequestUiWithUrl(
    const char* arg_url);
bool sendSetNightMode(
    int                    arg_nightMode);
bool sendRequestSiriAction(
    int                     arg_action);
bool sendTouchScreenUpdate(
    bool                 arg_press,
    uint16_t                  arg_x,
    uint16_t                  arg_y);
bool    sendTelephonyUpdate(
    int                    arg_index);

bool sendRfcommData(
    char*                arg_ptr,
    int                    arg_length);
bool    sendWifiInformation(
    const char*            arg_ssid,
    const char*            arg_passphrase,
    int                    arg_securityType,
    uint8_t                arg_channel);
void setBtMacAddr(char* arg_addr);
OSStatus sendForceKeyFrame();

bool sendChangeModes(const char* arg_screenBorrowId,
                     int arg_screenType,
                     int arg_screenPriority,
                     int arg_screenTake,
                     int arg_screenBorrow,
                     const char* arg_audioBorrowId,
                     int arg_audioType,
                     int arg_audioPriority,
                     int arg_audioTake,
                     int arg_audioBorrow,
                     int arg_phone,
                     int arg_speech,
                     int arg_turnByTurn);

bool sendMediaButtonUpdate(int arg_index);


bool sendKnobUpdate(char    selectButtonPressed,
                    char    homeButtonPressed,
                    char    backButtonPressed,
                    double  x,
                    double  y,
                    char    wheelPositionRelative);


/////////////////////////////////////////////////////////////////////////////

typedef void (*UseriAP2LinkStatus)(int status);
typedef int (*UseriAP2WriteData)(const char* buf, int len);
typedef void (*UserCarPlaySessionStart)();
typedef void (*UserCarPlaySessionStop)(void);
typedef int(*UserSwitchUsbMode)(int mode);
typedef void (*UserDeviceTimeUpdate)(long long time);
typedef void (*UserDeviceLanguageUpdate)(const char* lang);
typedef void (*UserCallStateUpdate)(const char* remoteId,
                                         const char* displayName,
                                         int status,
                                         int direction,
                                         const char* uuid,
                                         const char* addrBookId,
                                         const char* label,
                                         int service);

typedef void (*UserDeviceInformationUpdate)(const char* name, int name_len);
typedef void (*UserAirPlaySessionEnd)(void);
typedef void (*UserRequestUI)(void);
typedef void (*UserModesChanged)(int arg_screen,
        int arg_permScreen,
        int arg_audio,
        int arg_permAudio,
        int arg_speechEntity,
        int arg_speechMode,
        int arg_phoneCall,
        int arg_turnByTurn);
typedef void (*UserDisableBluetooth)(void);
typedef void (*UserAirPlayDuckAudio)(double inDurationSecs, double inVolume);
typedef void (*UserAirPlayUnduckAudio)(double inDurationSecs) ;
typedef void (*UserAirPlayAudioStreamStart)(int handle, int type, int rate, int bits, int channels,
                                      void*  inStream);
typedef void (*UserAirPlayAudioStreamStop)(int handle, int type);
typedef int(*UserAirPlayScreenStreamStart)();
typedef void (*UserAirPlayScreenStreamStop)();
typedef int (*UserAirPlayScreenStreamData)(const uint8_t* buf, int len);


typedef struct {
    UseriAP2LinkStatus          useriAP2LinkStatus_f;
    UseriAP2WriteData           useriAP2WriteData_f;
    UserCarPlaySessionStart       userCarPlaySessionStart_f;
    UserCarPlaySessionStop        userCarPlaySessionStop_f;
    UserSwitchUsbMode           userSwitchUsbMode_f;
    UserDeviceTimeUpdate         userDeviceTimeUpdate_f;
    UserDeviceLanguageUpdate     userDeviceLanguageUpdate_f;
    UserCallStateUpdate    userCallStateUpdate_f;
    UserDeviceInformationUpdate        userDeviceInformationUpdate_f;
    UserAirPlaySessionEnd             userAirPlaySessionEnd_f;
    UserRequestUI          userRequestUI_f;
    UserModesChanged             userModesChanged_f;
    UserDisableBluetooth        userDisableBluetooth_f;
    UserAirPlayDuckAudio        userAirPlayDuckAudio_f;
    UserAirPlayUnduckAudio      userAirPlayUnduckAudio_f;
    UserAirPlayAudioStreamStart       userAirPlayAudioStreamStart_f;
    UserAirPlayAudioStreamStop        userAirPlayAudioStreamStop_f;
    UserAirPlayScreenStreamStart       userAirPlayScreenStreamStart_f;
    UserAirPlayScreenStreamStop        userAirPlayScreenStreamStop_f;
    UserAirPlayScreenStreamData    userAirPlayScreenStreamData_f;
} UserInterfaceDelegate;

#define UserInterfaceDelegateInit( PTR ) memset( (PTR), 0, sizeof( UserInterfaceDelegate ) );

void UserInterfaceSetDelegate(const UserInterfaceDelegate* inDelegate);


#ifdef  __cplusplus
}
#endif
#endif //GDBUS_CARPLAYINTERFACE_H
